using System;
using System.Collections.Generic;
using UnityEngine;
using Newtonsoft.Json;
using Sirenix.OdinInspector;

public class ScannerDataSerializer : MonoBehaviour
{
    // 从ScannerRuntimeData获取参数并序列化
    public static string SerializeScannerRunTimeData(ScannerRuntime scanner)
    {
        if (scanner == null)
            return string.Empty;

        try
        {
            // 创建匿名类型，排除visitedCells字段以减小数据大小
            var dataToSerialize = new
            {
                scoreDir = scanner.scoreDir,
                collideDir = scanner.collideDir,
                pathDir = scanner.pathDir,
                leaderRangeDir = scanner.leaderRangeDir,
                directionRetentionDir = scanner.directionRetentionDir,
                finalMoveDir = scanner.finalMoveDir,
                position = scanner.position,
                forward = scanner.forward,
                leaderPosition = scanner.leaderPosition,
                leaderScanRadius = scanner.leaderScanRadius,
                otherScannerPositions = scanner.otherScannerPositions,
                // 故意排除visitedCells字段，以减小序列化后的数据大小
                visitedCells = scanner.visitedCells
            };

            return JsonConvert.SerializeObject(dataToSerialize, new VectorConverter());
        }
        catch (Exception ex)
        {
            Debug.LogError($"序列化ScannerRuntimeData失败: {ex.Message}");
            return string.Empty;
        }
    }

    // 从JSON反序列化参数到ScannerRuntimeData
    public static ScannerRuntime DeserializeToScannerRunTimeData(string jsonData)
    {
        if (string.IsNullOrEmpty(jsonData))
        {
            Debug.LogWarning("JSON数据为空，无法反序列化ScannerRuntimeData");
            return CreateDefaultRuntimeData();
        }

        try
        {
            // 先反序列化为匿名对象获取基本数据
            var tempData = JsonConvert.DeserializeObject<Dictionary<string, object>>(jsonData);

            // 创建新的ScriptableObject实例
            var runtimeData = CreateDefaultRuntimeData();

            // 使用JSON反序列化填充数据
            JsonConvert.PopulateObject(jsonData, runtimeData);

            return runtimeData;
        }
        catch (Exception ex)
        {
            Debug.LogError($"反序列化ScannerRuntimeData失败: {ex.Message}");
            return CreateDefaultRuntimeData();
        }
    }

    // 从ScannerConfigData获取参数并序列化
    public static string SerializeScannerConfigData(ScannerConfig scanner)
    {
        if (scanner == null)
            return string.Empty;

        try
        {
            var settings = new JsonSerializerSettings
            {
                ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
                Formatting = Formatting.Indented
            };

            return JsonConvert.SerializeObject(scanner, new VectorConverter());
        }
        catch (Exception ex)
        {
            Debug.LogError($"序列化ScannerConfigData失败: {ex.Message}");
            return string.Empty;
        }
    }

    // 从JSON反序列化参数到ScannerConfigData
    public static ScannerConfig DeserializeToScannerConfigData(string jsonData)
    {
        if (string.IsNullOrEmpty(jsonData))
        {
            Debug.LogWarning("JSON数据为空，无法反序列化ScannerConfigData");
            return CreateDefaultConfigData();
        }

        try
        {
            // 创建新的ScriptableObject实例
            var configData = CreateDefaultConfigData();

            // 使用JSON反序列化填充数据
            JsonConvert.PopulateObject(jsonData, configData);

            return configData;
        }
        catch (Exception ex)
        {
            Debug.LogError($"反序列化ScannerConfigData失败: {ex.Message}");
            return CreateDefaultConfigData();
        }
    }

    /// <summary>
    /// 创建默认的ScannerRuntimeData实例
    /// </summary>
    public static ScannerRuntime CreateDefaultRuntimeData()
    {
        var runtimeData = new ScannerRuntime();
        runtimeData.scoreDir = Vector3.forward;
        runtimeData.collideDir = Vector3.zero;
        runtimeData.pathDir = Vector3.forward;
        runtimeData.leaderRangeDir = Vector3.zero;
        runtimeData.directionRetentionDir = Vector3.forward;
        runtimeData.finalMoveDir = Vector3.forward;
        runtimeData.position = Vector3.zero;
        runtimeData.forward = Vector3.forward;
        runtimeData.leaderPosition = Vector3.zero;
        runtimeData.leaderScanRadius = 10f;
        runtimeData.visitedCells = new List<Vector3>();
        runtimeData.otherScannerPositions = new List<Vector3>();
        return runtimeData;
    }

    /// <summary>
    /// 创建默认的ScannerConfigData实例
    /// </summary>
    public static ScannerConfig CreateDefaultConfigData()
    {
        var configData = new ScannerConfig();
        // 设置默认配置值
        configData.repulsionCoefficient = 2f;
        configData.entropyCoefficient = 3f;
        configData.distanceCoefficient = 2f;
        configData.leaderRangeCoefficient = 3f;
        configData.directionRetentionCoefficient = 2f;
        configData.updateInterval = 0.2f;
        configData.moveSpeed = 2f;
        configData.rotationSpeed = 120f;
        configData.scanRadius = 5f;
        configData.maxRepulsionDistance = 5f;
        configData.minSafeDistance = 2f;
        configData.avoidRevisits = true;
        configData.targetSearchRange = 20f;
        configData.revisitCooldown = 60f;
        return configData;
    }
}


/// <summary> 
/// 两边传递的配置数据
/// </summary>
[Serializable]
public class ScannerConfig : IDataPack
{
    // 系数设置(Python配置)
    [Tooltip("排斥力系数：控制实体间相互排斥的强度（值越大排斥越明显，建议范围：1-5）")]
    public float repulsionCoefficient;

    [Tooltip("熵值系数：控制探索随机性权重（值越大实体越倾向随机移动，建议范围：1-10）")]
    public float entropyCoefficient;

    [Tooltip("距离系数：控制目标距离对移动决策的影响权重（值越大优先选择近距离目标）")]
    public float distanceCoefficient;

    [Tooltip("领导者范围系数：控制领导者对群体移动的影响强度（值越大群体越聚集）")]
    public float leaderRangeCoefficient;

    [Tooltip("方向保持系数：控制历史方向的惯性权重（值越大移动方向越稳定，建议范围：0.5-5）")]
    public float directionRetentionCoefficient;

    [Tooltip("数据更新间隔：Python与Unity间数据同步的时间间隔（单位：秒，建议范围：0.1-0.5）")]
    public float updateInterval;

    // 基础参数（Python配置）
    [Tooltip("移动速度：实体的线性移动速率（单位：米/秒，建议范围：1-10）")]
    public float moveSpeed;

    [Tooltip("旋转速度：实体的转向角速度（单位：度/秒，建议范围：60-200）")]
    public float rotationSpeed;

    [Tooltip("扫描半径：实体对周围环境的感知范围（单位：米，建议范围：3-20）")]
    public float scanRadius;

    // 排斥力参数（Python配置）
    [Tooltip("最大排斥距离：超过此距离后排斥力失效（单位：米，需大于minSafeDistance）")]
    public float maxRepulsionDistance;

    [Tooltip("最小安全距离：实体间必须保持的最小间隔（单位：米，小于此值触发强排斥）")]
    public float minSafeDistance;

    // 目标选择策略（Python配置）
    [Tooltip("是否避免重复访问：启用后实体将优先探索未访问区域（true=启用，false=禁用）")]
    public bool avoidRevisits;

    [Tooltip("目标搜索范围：实体主动搜索目标的最大距离（单位：米，建议范围：10-50）")]
    public float targetSearchRange;

    [Tooltip("重复访问冷却时间：已访问区域的再次访问间隔（单位：秒，建议范围：30-300）")]
    public float revisitCooldown;


    public void CopyByData(ScannerConfig data)
    {
        repulsionCoefficient = data.repulsionCoefficient;
        entropyCoefficient = data.entropyCoefficient;
        distanceCoefficient = data.distanceCoefficient;
        leaderRangeCoefficient = data.leaderRangeCoefficient;
        directionRetentionCoefficient = data.directionRetentionCoefficient;
        updateInterval = data.updateInterval;
        moveSpeed = data.moveSpeed;
        rotationSpeed = data.rotationSpeed;
        scanRadius = data.scanRadius;
        maxRepulsionDistance = data.maxRepulsionDistance;
        minSafeDistance = data.minSafeDistance;
        avoidRevisits = data.avoidRevisits;
        targetSearchRange = data.targetSearchRange;
        revisitCooldown = data.revisitCooldown;
    }
}

/// <summary>
/// 两边传递的实时数据
/// </summary>
[Serializable]
public class ScannerRuntime : IDataPack
{
    [Tooltip("无人机名字")] public string uavname;

    [Tooltip("评分方向向量：由Python计算的移动评分权重方向，影响移动决策优先级")]
    public Vector3 scoreDir;

    [Tooltip("碰撞规避方向向量：由Python计算的障碍物规避方向，用于避开静态/动态障碍物")]
    public Vector3 collideDir;

    [Tooltip("路径规划方向向量：由Python计算的最优路径方向，指向目标点或安全区域")]
    public Vector3 pathDir;

    [Tooltip("领导者范围方向向量：由Python计算的领导者影响范围方向，用于保持群体协同")]
    public Vector3 leaderRangeDir;

    [Tooltip("方向保持向量：由Python计算的历史方向惯性向量，减少移动方向突变")]
    public Vector3 directionRetentionDir;

    [Tooltip("最终移动方向向量：由Python综合所有方向计算得出，决定实体实际移动方向")]
    public Vector3 finalMoveDir;

    // 当前位置和方向信息（Unity提供）
    [Tooltip("实体当前世界空间位置坐标，由Unity实时更新（单位：米）")]
    public Vector3 position;

    [Tooltip("实体当前前向方向向量，由Unity实时更新（指示实体朝向）")]
    public Vector3 forward;

    // Leader信息（Unity提供）
    [Tooltip("领导者实体的世界空间位置坐标，由Unity提供给Python用于群体行为计算")]
    public Vector3 leaderPosition;

    [Tooltip("领导者的扫描感知半径，由Unity提供（单位：米），定义领导者的影响范围")]
    public float leaderScanRadius;

    // [Tooltip("已访问蜂窝网格坐标列表：记录实体已探索的区域网格，由Unity维护用于避免重复访问")]
    public List<Vector3> visitedCells = new List<Vector3>();

    [Tooltip("其他扫描者位置列表：记录同组其他扫描实体的实时位置，由Unity收集提供给Python用于群体避障")]
    public List<Vector3> otherScannerPositions = new List<Vector3>();


    public void CopyByData(ScannerRuntime data)
    {
        scoreDir = data.scoreDir;
        collideDir = data.collideDir;
        pathDir = data.pathDir;
        leaderRangeDir = data.leaderRangeDir;
        directionRetentionDir = data.directionRetentionDir;
        finalMoveDir = data.finalMoveDir;
    }
}

public interface IDataPack
{
}